package com.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.grid.Page;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 13-8-20
 * Time: 下午10:36
 * To change this template use File | Settings | File Templates.
 */

public class HqlGenerateUtil {

    private static final String SUFFIX_COMMA = ",";
    private static final String SUFFIX_KG = " ";
    /**模糊查询符号*/
    private static final String SUFFIX_ASTERISK = "*";
    private static final String SUFFIX_ASTERISK_VAGUE = "%";
    /**不等于查询符号*/
    private static final String SUFFIX_NOT_EQUAL = "!";
    private static final String SUFFIX_NOT_EQUAL_NULL = "!NULL";

    /**时间查询符号*/
    private static final String END = "end";
    private static final String BEGIN = "begin";
    /**
     * 自动生成查询条件HQL
     * 模糊查询
     * 【只对Integer类型和String类型的字段自动生成查询条件】
     * @param request
     * @param page
     * @throws Exception
     */
    public static void installHql(HttpServletRequest request,Class T,Page page) throws ParseException {
        page.setTableName(T.getSimpleName());
        page.setRequest(request);
      Map<String,String> queryParams= JSON.parseObject( page.getParams(), new TypeReference<Map<String, String>>() {});
        Map<String,String[]> query=  request.getParameterMap();
        Map<String, Object> params = new HashMap<String, Object>();
          StringBuilder sbHQL=new StringBuilder();
        sbHQL.append("1=1");
        for(Map.Entry<String, String[]> entry: query.entrySet()) {
                 String value= entry.getValue()[0];
            if(queryParams!=null && (value.length()>0 && queryParams.containsKey(entry.getKey()))) {
                String str= queryParams.get(entry.getKey());
                if ("datefield".equals(str)) {
                    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
                    String  realName=value;
                    realName=  StringUtils.replaceChars(realName, realName.substring(0, 1),realName.substring(0, 1).toLowerCase());
                    Date date;
                    if (value.length() == 19) {
                        date= sdf1.parse(value);
                    } else   {
                        date= sdf1.parse(value);
                    }
                    if (entry.getKey().contains(BEGIN)) {
                        realName = realName.substring(5, realName.length());
                        sbHQL.append(" and "+realName+" >= :"+realName);
                        params.put(realName,date);
                    }
                    else if(entry.getKey().contains(END))    {
                        realName = realName.substring(3, realName.length());
                        sbHQL.append(" and "+realName+" < :"+realName);
                        params.put(realName,DateUtil.dateAddDay(date,1));
                    }
                } else if ("combo".equals(str)) {
                    sbHQL.append(" and "+entry.getKey()+" =:"+entry.getKey());
                    params.put(entry.getKey(),value);
                } else if ("textfield".equals(str)) {
                    sbHQL.append(" and "+entry.getKey()+" like :"+entry.getKey());
                    params.put(entry.getKey(),"%"+value+"%");
                } else if ("checkboxgroup".equals(str)) {
                    sbHQL.append(" and "+entry.getKey()+" in :"+entry.getKey());
                    params.put(entry.getKey(),value);
                }
            }

           // System.out.print(entry.getKey() + ":" + value + "\t");
        }
        page.setWhere(sbHQL.toString());
        page.setWhereParams(params);
    }


  	  	  	/*
  	 * 下面的方法是重载 org.jeecgframework.core.extend.hqlsearch.HqlGenerateUtil.installHql(CriteriaQuery, Object)
  	 * 其目的是拓展区间查询功能
  	 * 注：
  	 * 	重载此方法后修改了模版 controllerTemplate.ftl#datagrid()
  	 * 	将第二行<br/>
  	 * 		org.jeecgframework.core.extend.hqlsearch.HqlGenerateUtil.installHql(cq, ${entityName?uncap_first});
  	 * 	改为<br/>
  	 * 		org.jeecgframework.core.extend.hqlsearch.HqlGenerateUtil.installHql(cq, ${entityName?uncap_first}, request.getParameterMap());
  	 * 	因模版里不方便注释，故在此处说明
  	 */
//    /**
//     * 自动生成查询条件HQL（扩展区间查询功能）
//     * @param cq
//     * @param searchObj
//     * @param parameterMap 	request参数集合，封装了所有查询信息
//     */
//    public static void installHql(CriteriaQuery cq,Object searchObj, Map<String, String[]> parameterMap){
//        PropertyDescriptor origDescriptors[] = PropertyUtils.getPropertyDescriptors(searchObj);
//        // 获得对象属性中的name
//        String descriptorsNames = getDescriptorsNames(origDescriptors);
//
//        for (int i = 0; i < origDescriptors.length; i++) {
//            String name = origDescriptors[i].getName();
//            String type = origDescriptors[i].getPropertyType().toString();
//
//            if ("class".equals(name)||"ids".equals(name)||"page".equals(name)
//                    ||"rows".equals(name)||"sort".equals(name)||"order".equals(name)) {
//                continue; // No point in trying to set an object's class
//            }
//            try {
//                if (PropertyUtils.isReadable(searchObj, name)) {
//
//                    // 添加 判断是否有区间值
//                    String beginValue = null;
//                    String endValue = null;
//                    if (parameterMap.containsKey(name+"_begin")) {
//                        beginValue = parameterMap.get(name+"_begin")[0].trim();
//                    }
//                    if (parameterMap.containsKey(name+"_end")) {
//                        endValue = parameterMap.get(name+"_end")[0].trim();
//                    }
//
//                    // 根据类型分类处理
//                    if("class java.lang.String".equals(type)){
//                        Object value = PropertyUtils.getSimpleProperty(searchObj, name);
//                        String searchValue = null;
//                        if(value!=null){
//                            searchValue = value.toString().trim();
//                        }else{
//                            continue;
//                        }
//                        if(searchValue!=null&&!"".equals(searchValue)){
//                            //[1].In 多个条件查询{逗号隔开参数}
//                            if(searchValue.indexOf(SUFFIX_COMMA)>=0){
//                                //页面输入查询条件，情况（取消字段的默认条件）
//                                if(searchValue.indexOf(SUFFIX_KG)>=0){
//                                    String val = searchValue.substring(searchValue.indexOf(SUFFIX_KG));
//                                    cq.eq(name, val);
//                                }else{
//                                    String[] vs = searchValue.split(SUFFIX_COMMA);
//                                    cq.in(name, vs);
//                                }
//                            }
//                            //[2].模糊查询{带有* 星号的参数}
//                            else if(searchValue.indexOf(SUFFIX_ASTERISK)>=0){
//                                cq.like(name, searchValue.replace(SUFFIX_ASTERISK, SUFFIX_ASTERISK_VAGUE));
//                            }
//                            //[3].不匹配查询{等于！叹号}
//                            //(1).不为空字符串
//                            else if(searchValue.equals(SUFFIX_NOT_EQUAL)){
//                                cq.isNotNull(name);
//                            }
//                            //(2).不为NULL
//                            else if(searchValue.toUpperCase().equals(SUFFIX_NOT_EQUAL_NULL)){
//                                cq.isNotNull(name);
//                            }
//                            //(3).正常不匹配
//                            else if(searchValue.indexOf(SUFFIX_NOT_EQUAL)>=0){
//                                cq.notEq(name, searchValue.replace(SUFFIX_NOT_EQUAL, ""));
//                            }
//                            //[4].全匹配查询{没有特殊符号的参数}
//                            else{
//                                cq.eq(name, searchValue);
//                            }
//                        }
//                    }else if("class java.lang.Integer".equals(type)){
//                        if (beginValue != null && !"".equals(beginValue)) {
//                            cq.ge(name, Integer.parseInt(beginValue));
//                        }
//                        if (endValue != null && !"".equals(endValue)) {
//                            cq.le(name, Integer.parseInt(endValue));
//                        }
//                        Object value = PropertyUtils.getSimpleProperty(searchObj, name);
//                        if(value!=null&&!"".equals(value)){
//                            cq.eq(name, value);
//                        }
//                    } else if("class java.math.BigDecimal".equals(type)){
//                        if (beginValue != null && !"".equals(beginValue)) {
//                            if (beginValue.contains(".")) {
//                                cq.ge(name, BigDecimal.valueOf(Double.parseDouble(beginValue)));
//                            } else {
//                                cq.ge(name, BigDecimal.valueOf(Long.parseLong(beginValue)));
//                            }
//                        }
//                        if (endValue != null && !"".equals(endValue)) {
//                            if (beginValue.contains(".")) {
//                                cq.le(name, BigDecimal.valueOf(Double.parseDouble(endValue)));
//                            } else {
//                                cq.le(name, BigDecimal.valueOf(Long.parseLong(endValue)));
//                            }
//                        }
//                        Object value = PropertyUtils.getSimpleProperty(searchObj, name);
//                        if(value!=null&&!"".equals(value)){
//                            cq.eq(name, value);
//                        }
//                    }else if("class java.lang.Short".equals(type)){
//                        if (beginValue != null && !"".equals(beginValue)) {
//                            cq.ge(name, Short.parseShort(beginValue));
//                        }
//                        if (endValue != null && !"".equals(endValue)) {
//                            cq.le(name, Short.parseShort(endValue));
//                        }
//                        Object value = PropertyUtils.getSimpleProperty(searchObj, name);
//                        if(value!=null&&!"".equals(value)){
//                            cq.eq(name, value);
//                        }
//                    }else if("class java.lang.Long".equals(type)){
//                        if (beginValue != null && !"".equals(beginValue)) {
//                            cq.ge(name, Long.parseLong(beginValue));
//                        }
//                        if (endValue != null && !"".equals(endValue)) {
//                            cq.le(name, Long.parseLong(endValue));
//                        }
//                        Object value = PropertyUtils.getSimpleProperty(searchObj, name);
//                        if(value!=null&&!"".equals(value)){
//                            cq.eq(name, value);
//                        }
//                    }else if ("class java.util.Date".equals(type)) {
//                        // 由于前台使用时间控件，目前仅提供下面两种格式支持。
//                        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//                        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
//                        if (StringUtils.isNotBlank(beginValue)) {
//                            if (beginValue.length() == 19) {
//                                cq.ge(name, sdf1.parse(beginValue));
//                            } else if (beginValue.length() == 10) {
//                                cq.ge(name, sdf2.parse(beginValue));
//                            }
//                        }
//                        if (StringUtils.isNotBlank(endValue)) {
//                            if (endValue.length() == 19) {
//                                cq.le(name, sdf1.parse(endValue));
//                            } else if (endValue.length() == 10) {
//                                // 对于"yyyy-MM-dd"格式日期，因时间默认为0，故此添加" 23:23:59"并使用sdf1解析，以方便查询日期时间数据
//                                cq.le(name, sdf1.parse(endValue + " 23:23:59"));
//                            }
//                        }
//                        Object value = PropertyUtils.getSimpleProperty(searchObj, name);
//                        if(value!=null&&!"".equals(value)){
//                            cq.eq(name, value);
//                        }
//                        if (null != value) {
//                            // 判断开始时间
//                            if (name.contains(BEGIN)) {
//                                String realName = StringUtil.firstLowerCase(name.substring(5, name.length()));
//                                if (!BEGIN.equals(name.substring(0, 5)) || !descriptorsNames.contains(realName)) {
//                                    logger.error("该查询属性 [" + name + "] 命名不规则");
//                                } else {
//                                    cq.ge(realName, value);
//                                }
//                            }
//                            // 判断结束时间
//                            else if (name.contains(END)) {
//                                String realName = StringUtil.firstLowerCase(name.substring(3, name.length()));
//                                if (!END.equals(name.substring(0, 3)) || !descriptorsNames.contains(realName)) {
//                                    logger.error("该查询属性 [" + name + "] 命名不规则");
//                                } else {
//                                    cq.le(name, value);
//                                }
//                            }
//                            else {
//                                cq.eq(name, value);
//                            }
//                        }
//                    }
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//        //添加选择条件
//        cq.add();
//    }
//
//
}


